from typing import Dict

from django.conf import settings
from django.utils.translation import gettext_lazy as _
from django.core.cache import cache as dj_cache

from ceph.models import GlobalConfig


class Singleton(type):
    def __call__(cls, *args, **kwargs):
        if not hasattr(cls, '_instance'):
            cls._instance = super().__call__(*args, **kwargs)

        return cls._instance


class Configs(metaclass=Singleton):
    ConfigName = GlobalConfig.ConfigName
    CACHE_KEY = 'evcloud_app_global_configs_cache'

    @staticmethod
    def get_configs_no_cache(remove_invalid: bool = False) -> Dict[str, str]:
        qs = GlobalConfig.objects.all().values('name', 'content')
        configs = {}
        invalid_names = []
        conf_names = GlobalConfig.ConfigName.values
        for cfg in qs:
            name = cfg['name']
            if name in conf_names:
                configs[cfg['name']] = cfg['content']
            else:
                invalid_names.append(name)

        if remove_invalid and invalid_names:
            GlobalConfig.objects.filter(name__in=invalid_names).delete()

        # 缺少配置
        if len(configs) < len(conf_names):
            for name in conf_names:
                if name not in configs:
                    def_values = GlobalConfig.value_defaults[name]
                    if isinstance(def_values, dict):
                        value = def_values.get('content', '')
                        remark = def_values.get('remark', '')
                    else:
                        value = def_values
                        remark = ''

                    obj, created = GlobalConfig.objects.get_or_create(
                        name=name, defaults={'content': value, 'remark': remark})
                    configs[name] = obj.content

        return configs

    @staticmethod
    def get_configs() -> Dict[str, str]:
        cache_key = Configs.CACHE_KEY
        configs = dj_cache.get(cache_key)
        if configs:
            return configs

        configs = Configs.get_configs_no_cache(remove_invalid=False)
        dj_cache.set(cache_key, configs, timeout=120)


        passport_jwt = getattr(settings, 'PASSPORT_JWT', None)
        if passport_jwt and GlobalConfig.ConfigName.AAI_JWT_VERIFYING_KEY.value in configs and passport_jwt[
            'VERIFYING_KEY'] != configs[GlobalConfig.ConfigName.AAI_JWT_VERIFYING_KEY.value]:
            settings.PASSPORT_JWT['VERIFYING_KEY'] = configs[GlobalConfig.ConfigName.AAI_JWT_VERIFYING_KEY.value]

        return configs

    @staticmethod
    def clear_cache():
        dj_cache.delete(Configs.CACHE_KEY)

    def get(self, name: str):
        """
        查询参数
        """
        if name not in GlobalConfig.ConfigName.values:
            raise Exception(_('未知的全局参数'))

        configs = self.get_configs()
        return configs[name]

    def check_site_parameter_resource_admin(self):
        """ 检查站点参数：中坤管理员格式 """
        qs = GlobalConfig.objects.filter(name=GlobalConfig.ConfigName.RESOURCE_ADMIN.value).first()
        if not qs:
            return

        if ',' in qs.content:
            content_list = qs.content.split(',')
            qs.content = '\n'.join(content_list)
            qs.save(update_fields=['content'])
        elif '，' in qs.content:
            content_list = qs.content.split('，')
            qs.content = '\n'.join(content_list)
            qs.save(update_fields=['content'])
        else:
            raise Exception(f'未识别到","或"，"格式，具体信息如下：\n{qs.content}')


global_configs = Configs()
